<template>
  <div :style="{ height: height ? height : 'auto' }" class="list">
    <el-table
      :data="listData"
      :ref="tableRef"
      :border="border"
      size="medium"
      height="100%"
      :highlight-current-row="highlight"
      @current-change="currentChange"
      @sort-change="sortChange"
      @cell-dblclick="cellDoubleClick"
      @selection-change="selectionChange"
      @row-contextmenu="rowContextmenu"
      @row-click="rowClick"
      @header-dragend="headerDragend"
      @select="rowSelect"
      @select-all="rowSelectAll"
      :show-overflow-tooltip="true"
    >
      <!-- 选择框 -->
      <el-table-column
        v-if="hasSelect"
        type="selection"
        width="55"
        min-width="55"
        align="center"
      ></el-table-column>
      <!-- 序号 -->
      <el-table-column
        v-if="showIndex"
        type="index"
        :index="indexMethod"
        align="center"
        width="55"
        min-width="55"
        label="序号">
      </el-table-column>
      <!-- 每列 -->
      <el-table-column
        v-for="col in listCols"
        :show-overflow-tooltip="true"
        :key="col.prop"
        :prop="col.prop"
        :min-width="col.minwidth"
        :width="col.width"
        :label="$t(col.label)"
        :align="col.align || 'center'"
        :sortable="col.sortable || false"
      >
        <template slot-scope="{ row, column, $index }">
          <template v-if="col.slot">
            <slot
              :name="col.prop + 'Slot'"
              :row="row"
              :column="column"
              :$index="$index"
            ></slot>
          </template>
          <template v-else>{{ row[col.prop] }}</template>
        </template>
      <!-- 下拉选项 -->
        <template slot="header" slot-scope="{ column, $index }">
          <template v-if="col.headerSlot">
            <slot
              :name="col.prop + 'HeaderSlot'"
              :column="column"
              :$index="$index"
            ></slot>
          </template>
          <template v-else>
            {{ column.label }}
            <template v-if="col.headerContextMenus">
              <span
                style="float: right"
                :class="[`${col.prop}-hmbtn`]"
                @click.stop="(e) => showHeaderMenu(col.prop, e)"
              >
                <i class="el-icon-caret-bottom"></i>
              </span>
              <!-- <list-header-menu
                :ref="col.prop+'-hm'"
                :element-id="col.prop+'-hm'"
                :options="_genHeaderMenus(col.headerContextMenus, col.prop)"
                @option-clicked="(v) => headerMenuClicked(v, col.prop)"
              />-->
              <!-- <list-header-menu
                :ref="col.prop+'-hm'"
                :element-id="col.prop+'-hm'"
                :options="col.headerContextMenus"
              />-->
            </template>
          </template>
        </template>
      </el-table-column>
      <!-- 操作列 -->
      <el-table-column
        v-if="actionOpts.show"
        :label="$t(actionOpts.name)"
        :align="actionOpts.align"
        :fixed="actionOpts.fixed"
        :min-width="actionOpts.width"
      >
        <template slot-scope="{ row, column, $index }">
          <el-button
            class="smini-btn"
            v-if="!actionOpts.hidEditBtn"
            type="primary"
            size="mini"
            @click="handleActionBtn('edit', row)"
            >编辑</el-button
          >
          <el-button
            class="smini-btn"
            v-if="!actionOpts.hidDelBtn"
            type="danger"
            size="mini"
            @click="handleActionBtn('del', row)"
            >删除</el-button
          >
          <!-- 查看按钮 -->
          <slot
            v-if="actionOpts.slot"
            name="actionSlot"
            :row="row"
            :column="column"
            :$index="$index"
          ></slot>
        </template>
      </el-table-column>
    </el-table>

    <!-- <context-menu
      element-id="listContextMenu"
      ref="listContextMenu"
      @option-clicked="listContextMenuClicked"
      :options="contextMenus"
    ></context-menu> -->

    <!-- 头部菜单渲染（下拉框内容） -->
    <!-- <list-header-menu
      v-for="col in hasHMCols"
      :key="col.prop + '-hm'"
      :ref="col.prop + '-hm'"
      :element-id="col.prop + '-hm'"
      :options="hmOptionsMap[col.prop]"
      @option-clicked="(v) => headerMenuClicked(v, col.prop)"
    /> -->
  </div>
</template>

<script>
// import ContextMenu from './components/ContextMenu'
// import ListHeaderMenu from './components/ListHeaderMenu'

export default {
  // components: {
  //   ContextMenu,
  //   ListHeaderMenu,
  // },
  props: {
    // 是否显示序号
    showIndex: {
      type: Boolean,
      default: false
    },
    // 当前页
    page: {
      type: Number,
      default: 1
    },
    // 当前页数量
    limit: {
      type: Number,
      default: 0
    },
    tableRef: {
      type: String,
      default:'list'
    },
    contextMenus: {
      type: Array,
      default() {
        return []
      },
    },
    border:{
      type: Boolean,
      default: false,
    },
    sortable: {
      type: [Boolean, String],
      default: false,
    },
    // 是否能选择，多选
    hasSelect: {
      type: Boolean,
      default: false,
    },
    // 是否要高亮当前行
    highlight: {
      type: Boolean,
      default: false,
    },
    listData: {
      type: Array,
      default() {
        return []
      },
    },
    listCols: {
      type: Array,
      default() {
        return []
      },
    },
    // 默认要显示的列的prop合集
    // initColsProps: {
    //   type: [Array, Boolean],
    //   default() {
    //     return false
    //   },
    // },
    actionOpts: {
      type: Object,
      default() {
        return {
          show: true,
          align: 'center',
          width: '120px',
          name: '操作',
        }
      },
    },
    height: {
      type: String,
      default: '',
    },
    tableTag: {
      type: String,
      default() {
        return window.location.pathname
      },
    },
    initHeadmuneFlag: {
      // 初始化头部菜单标识
      type: [Boolean, String],
      default: 'auto',
    },
    noStorage: {
      // 不需要记忆功能
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      activeItem: [],
      colFilterBoolMap: {}, // 列过滤是否启用索引
      colFilterValMap: {}, // 列过滤input值索引
      inputTimer: null, // input节流计时器
      hmOptionsMap: {}, // 头部菜单索引
      needShowColsMenu: [], // 显隐列菜单
      hmOpenedId: '', // 当前打开的头部菜单id
      tableConfig: {
        cols: [],
        colWidths: {},
        sort: {},
      },
      initConfigDone: false
    }
  },
  computed: {
    cols() {
      // if (!this.initColsProps) {
      //   return [...this.listCols]
      // } else if (this.initColsProps instanceof Array) {
      //   return this.listCols.filter(
      //     (col) => this.initColsProps.indexOf(col.prop) > -1
      //   )
      // } else {
      //   return []
      // }
      return []
    },
    hasHMCols() {
      console.log('hasHMCols')
      // 拥有头部菜单的列
      return this.listCols.filter((col) => col.headerContextMenus)
    },
    currentProps: {
      get() {
        return this.initColsProps
      },
      set(v) {},
    },
  },
  watch: {
    initColsProps: {
      handler(val) {
        this.currentProps = val
        this.editTableConfig()
      },
    },
    hasHMCols: {
      immediate: true,
      handler(v) {
        if (this.initHeadmuneFlag !== 'auto' || !this.initConfigDone) return
        this.renderHmOptinsMap(v)
      },
    },
    initHeadmuneFlag(v) {
      if (v === true) {
        this.renderHmOptinsMap(this.hasHMCols)
      }
    },
  },
  methods: {
    // 渲染头部菜单
    renderHmOptinsMap(hasHMCols) {
      const map = {}
      hasHMCols.forEach((element) => {
        map[element.prop] = this._genHeaderMenus(
          element.headerContextMenus,
          element.prop
        )
      })
      this.hmOptionsMap = map
    },

    //--------------表头配置处理-----------------
    initConfig() {
      var config = JSON.parse(sessionStorage.getItem(this.tableTag))
      console.log('initConfig = ' + JSON.stringify(config))
      if (!this.noStorage && config) {
        this.tableConfig = config
        if (config.cols.length > 0) {
          this.$emit('update:initColsProps', config.cols)
        }
        this.cols.forEach((element, index) => {
          if (config.cols[config.cols.length - 1] != element.prop) {
            element.width = config.colWidths[element.prop]
          }
        })
      }
      this.initConfigDone = true
      // 修复自动初始化头部时还未拿到配置问题
      if (this.initHeadmuneFlag === 'auto') {
        this.$nextTick(() => {
           this.renderHmOptinsMap(this.hasHMCols)
        })
      }
      this.$emit('init-table', this.tableConfig)
    },

    editTableConfig() {
      if (this.noStorage) return ;
      this.tableConfig.cols = this.currentProps
      sessionStorage.setItem(this.tableTag, JSON.stringify(this.tableConfig))
      console.log('editRoleConfig = ' + JSON.stringify(this.tableConfig))
      if (this.tableConfig.cols.length === 1) {
        if (this.needShowColsMenu.length>0) {
            this.needShowColsMenu.forEach((element) => {
              if (element.prop === this.tableConfig.cols[0]) {
                element.disabled = true
              }
            })
        }
      }else{
        this.needShowColsMenu.forEach((element) => {
                element.disabled = false
            })
      }
    },

    handleActionBtn(type, rowData) {
      this.$emit(`${type}Click`, JSON.parse(JSON.stringify(rowData)))
    },
    sortChange({ column, prop, order }) {
      this.sortable === 'custom' &&
        this.$emit('sort-change', { column, prop, order })
    },
    selectionChange(selection) {
      this.activeItem = selection
      this.$emit('selection-change', selection)
    },
    cellDoubleClick(row, column, cell, event) {
      this.$emit('cell-double-click', row, column, cell, event)
    },
    currentChange(val) {
      this.$emit('cunrrent-change', val)
    },
    rowClick(row, column, event) {
      this.$emit('row-click', row, column, event)
    },
    rowSelect(selection,row){
      this.$emit('row-select', row, selection)
    },
    rowSelectAll(selection){
      this.$emit('row-select-all', selection)
    },
    headerDragend(newWidth, oldWidth, column, event) {
      let key = column.property
      this.tableConfig.colWidths[key] = newWidth
      this.editTableConfig()
      console.log('headerDragend newwidth 111= ' + newWidth)
      this.$emit('header-dragend', newWidth, oldWidth, column, event)
      this.$nextTick(() => {
        this.$refs[this.tableRef].doLayout()
      })
    },
    getActiveItem() {
      return [...this.activeItem]
    },
    rowContextmenu(row, column, event) {
      if (this.contextMenus.length < 1) return
      event.preventDefault()
      this.$refs.listContextMenu.showMenu(event, row)
    },
    listContextMenuClicked(item) {
      if (this.contextMenus.length < 1) return
      this.$emit('contextMenuClicked', item)
    },
    showHeaderMenu(prop, event) {
      console.log('cols = ' + this.initColsProps)
      // console.log(this.$refs[prop+'-hm'][0])
      const id = prop + '-hm'
      if (this.hmOpenedId && this.hmOpenedId !== id) {
        this.$refs[this.hmOpenedId][0].hideContextMenu()
      }
      this.$refs[prop + '-hm'][0].showMenu(event)
      this.hmOpenedId = id
    },
    headerMenuClicked(item, prop) {
      console.log(item,prop)
      let sort = {}
      switch (item.option.type) {
        case 'sortUp':
          sort = {
            type: 'ASC',
            prop,
          }
          this.$emit('sort', sort)
          this.tableConfig.sort = sort
          this.editTableConfig()
          break
        case 'sortDown':
          sort = {
            type: 'DESC',
            prop,
          }
          this.$emit('sort', sort)
          this.tableConfig.sort = sort
          this.editTableConfig()
          break
        default:
      }
    },

    /*****    生成表头的额外功能菜单 开始      *****/
    _genHeaderMenus({ width, items }, colProp) {
      const options = {} // 最终生成的额外功能配置
      const itemMap = {
        sortUp: {
          name: this.$t('升序'),
          icon: 'iconfont icon-shengxu',
          type: 'sortUp',
        },
        sortDown: {
          name: this.$t('降序'),
          icon: 'iconfont icon-jiangxu1',
          type: 'sortDown',
        },
        line: {
          type: 'divider',
        },
        cols: {
          name: this.$t('列'),
          icon: 'iconfont icon-liebiao',
        },
        filter: {
          name: '过滤',
          type: 'checkbox',
        },
      }

      // 一层菜单的宽度设置
      options.width = width || '120px'
      // 一层菜单项生成
      options.items = items.map((item) => {
        if (item === 'cols') {
          // 显隐列生成
          return {
            ...itemMap.cols,
            children: this._genColsMenu(),
          }
        } else if (item === 'filter') {
          // 过滤功能
          const filter = {
            ...itemMap.filter,
            value: false,
            changeFn: (v) => {
              this._filterCheckChange(v, colProp)
            },
            children: this._genFilterMenu(colProp),
          }
          this.$set(this.colFilterBoolMap, colProp, filter)
          // this.colFilterBoolMap[colProp] = filter
          return filter
        } else {
          return itemMap[item]
        }
      })

      return options
    },
    // 生成列显隐菜单
    _genColsMenu() {
      const menu = {}
      menu.width = '180px'
      if (this.needShowColsMenu.length < 1) {
        this.needShowColsMenu = this.listCols.map((col) => {
          let enable
          if(this.initColsProps.length == 1&&this.initColsProps[0]==col.prop){
            enable = true
          }else{
            enable = false
          }
          return {
            type: 'checkbox',
            name: col.label,
            disabled: enable,
            prop:col.prop,
            value: this.initColsProps.indexOf(col.prop) > -1,
            changeFn: (v) => {
              this._colsChange(v, col.prop)
            },
          }
        })
      }
      menu.items = this.needShowColsMenu

      return menu
    },
    // 列显隐菜单事件回调
    _colsChange(isShow, prop) {
      const _initColsProps = [...this.initColsProps]
      if (isShow) {
        _initColsProps.push(prop)
      } else {
        _initColsProps.splice(_initColsProps.indexOf(prop), 1)
      }
      this.$emit('update:initColsProps', _initColsProps)

      this.$nextTick(() => {
        this.$refs.list.doLayout()
      })
    },
    // 生成过滤菜单
    _genFilterMenu(colProp) {
      // const _pureColFilterValMap = JSON.parse(JSON.stringify(this.colFilterValMap))
      // console.log(_pureColFilterValMap, '---2')
      const menu = {}
      menu.width = '160px'
      const filterInput = {
        class: 'filter-input',
        type: 'input',
        icon: 'iconfont icon-shaixuan',
        value: '',
        changeFn: (v) => {
          this._inputChange(v, colProp)
        },
      }
      this.$set(this.colFilterValMap, colProp, filterInput)
      // this.colFilterValMap[colProp] = filterInput
      menu.items = [filterInput]
      return menu
    },
    // 过滤input框事件回调
    _inputChange(v, colProp) {
      if (this.inputTimer) {
        clearTimeout(this.inputTimer)
      }
      this.inputTimer = setTimeout(() => {
        this.$emit('filter', {
          value: v,
          prop: colProp,
        })
        this.$nextTick(() => {
          if (!v) {
            this.colFilterBoolMap[colProp].value = false
          } else if (!this.colFilterBoolMap[colProp].value) {
            this.colFilterBoolMap[colProp].value = true
          }
        })
      }, 800)
    },
    // 过滤checkbox事件回调
    _filterCheckChange(v, colProp) {
      // 开启 - 传input值  关闭 - 传空字符串
      this.$emit('filter', {
        value: v ? this.colFilterValMap[colProp].value : '',
        prop: colProp,
      })
    },
    clearSelection() {
      this.$refs.list.clearSelection()
    },
    /*****    生成表头的额外功能菜单 结束      *****/
    indexMethod(index) {
      return (index + 1) + (this.page - 1) * this.limit
    },
    toggleSelection(row) {
      if (row) {
        this.$refs[this.tableRef].toggleRowSelection(row);
      }
    },
  },
  mounted() {
    // console.log(this.listCols)
  },
  created() {
    this.initConfig()
  },
  beforeDestroy() {
    this.inputTimer && clearTimeout(this.inputTimer)
  },
}
</script>

<style lang="scss" scoped>
.list {
  position: relative;
}
::v-deep .el-table colgroup.gutter {
  display: table-cell !important;
}
::v-deep .vue-simple-context-menu2__item {
  color: #ccc !important;
  padding:8px 15px;
}
::v-deep .vue-simple-context-menu2__divider{padding:0!important;}
::v-deep .iconfont {
  font-size: 14px !important;
}
::v-deep .icon-shaixuan {
  font-size: 20px !important;
}
</style>
